home *** CD-ROM | disk | FTP | other *** search
- /* #[info: */
- /************************************************************************
- * *
- * #### # # # ##### ####### ##### # # *
- * # # # ## ## # ### # # # # *
- * # # # # ## # # # # # # # # *
- * # ## ####### # # ### # # ### # *
- * # # # # # # # # # # # # *
- * # # # # # # # # # # # # *
- * #### # # # # ##### ###### # ##### # # *
- * *
- * Jan van der Steen *
- * *
- * Centre for Mathematics and Computer Science *
- * Amsterdam, the Netherlands *
- * *
- *----------------------------------------------------------------------*
- * File : game2tex.c *
- * Purpose : Emit a Go Game Using TeX directives *
- * Version : 1.27 *
- * Modified: 3/5/93 17:34:46 *
- * Author : Jan van der Steen (jansteen@cwi.nl) *
- ************************************************************************/
- /* #]info: */
- /* #[include: */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <time.h>
- #include "gogame.h"
- #include "game2asc.h"
- #include "game2tex.h"
- #include "game2eps.h"
- #include "tools.h"
- #include "sysdep.h"
-
- /* #]include: */
- /* #[define: */
-
- #define MAXUSER 1024 /* Maximum length of username */
-
- /* #]define: */
- /* #[extern: */
-
- extern int prn_dev;
- extern EPSFINFO epsf;
- extern int figlist[]; /* Figure list */
- extern int dialist[]; /* Diagram list */
- extern int user_figs; /* Users fig list? */
- extern int user_dias; /* Users dia list? */
- extern int textout; /* Emit the text too */
- extern int statout; /* Emit the kibitz stats */
-
- /* #]extern: */
- /* #[prototype: */
-
- #ifdef __STDC__
- # define PROTO(s) s
- #else
- # define PROTO(s) ()
- #endif
-
- static void tex_header PROTO((GOGAME *g));
- static void tex_trailer PROTO((void));
- static void tex_text PROTO((GOMOVE *m, int label));
- static void text2tex PROTO((char *t));
- static void move2tex PROTO((GOGAME *g, GOMOVE *m1, GOMOVE *m2,
- int dianr));
-
-
- #undef PROTO
-
- /* #]prototype: */
-
- /* #[list2tex: */
-
- void
- list2tex(gogame)
- /*
- * Print the game according to the user defined list of figures.
- * Exchange kibitz and move and label the text output with move number.
- */
- GOGAME *gogame;
- {
- /*
- * Diagram handling
- */
- GOMOVE * m;
- GOMOVE * m1 = gogame->gm_move;
- GOMOVE * m2 = gogame->gm_move;
- /*
- * Text handling
- */
- GOMOVE * t;
- int dianr = 0;
- int fx = 0;
-
- tex_header(gogame);
-
- for (m = gogame->gm_move; m != (GOMOVE *) 0; m = m->mv_next) {
- m2 = m;
- if (m->mv_nr == figlist[fx]) {
- move2tex(gogame, m1, m, ++dianr);
- m2 = m->mv_next;
- /*
- * Print all text associated with this diagram
- */
- for (t = m1; t != m2; t = t->mv_next) {
- if (t->mv_text != (TEXT *) 0) tex_text(t, 1);
- }
- m1 = m->mv_next;
- fx++;
- }
- }
- /*
- * Print diagram with the left-overs
- */
- if (figlist[fx] && m1 != (GOMOVE *) 0) {
- move2tex(gogame, m1, m2, ++dianr);
- /*
- * Print all text associated with this diagram
- */
- for (t = m1; t != m2; t = t->mv_next) {
- if (t->mv_text != (TEXT *) 0) tex_text(t, 1);
- }
- }
-
- tex_trailer();
- }
-
- /* #]list2tex: */
- /* #[game2tex: */
-
- void
- game2tex(gogame)
- /*
- * Print the game events, exchanging kibitz and move
- */
- GOGAME *gogame;
- {
- GOMOVE *m;
- GOMOVE *p1 = gogame->gm_move;
- GOMOVE *p2 = gogame->gm_move;
- int dianr = 0;
-
- tex_header(gogame);
-
- for (m = gogame->gm_move; m != (GOMOVE *) 0; p2 = m, m = m->mv_next) {
- if (m->mv_text != (TEXT *) 0) {
- if (p1 != m) {
- move2tex(gogame, p1, m->mv_prev, ++dianr);
- p1 = m;
- }
- tex_text(m, 0);
- }
- }
- move2tex(gogame, p1, p2, ++dianr);
-
- tex_trailer();
- }
-
- /* #]game2tex: */
-
- /* #[tex_header: */
-
- static void
- tex_header(gogame)
- GOGAME *gogame;
- {
- GOGAME *g = gogame;
-
- /*
- * Ascii header of final position
- */
- fprintf(stdout, "%%%% #[Final position:\n");
- game2ascii(gogame);
- fprintf(stdout, "%%%% #]Final position: \n");
-
- /*
- * Document header
- */
- fprintf(stdout, "\\documentstyle[a4wide%s,sgf%s]{article}\n",
- (prn_dev == DEVICE_EPS) ? ",epsf" : "",
- (prn_dev == DEVICE_TEX) ? ",go" : "");
- switch (prn_dev) {
- case DEVICE_TEX:
- fprintf(stdout, "\\gofontsize{8}\n");
- break;
- case DEVICE_EPS:
- fprintf(stdout, "\\special{header=gopro.eps}\n");
- break;
- }
-
- /*
- * Title page
- */
- fprintf(stdout, "\\title{%%\n");
- fprintf(stdout, " \\centerline{");
- text2tex((g->gm_black) ? g->gm_black : "NN");
- fprintf(stdout, ", ");
- text2tex((g->gm_brank) ? g->gm_brank : "NR");
- fprintf(stdout, "}\n");
- fprintf(stdout, " \\centerline{versus}\n");
- fprintf(stdout, " \\centerline{");
- text2tex((g->gm_white) ? g->gm_white : "NN");
- fprintf(stdout, ", ");
- text2tex((g->gm_wrank) ? g->gm_wrank : "NR");
- fprintf(stdout, "}\n");
- fprintf(stdout, "}\n");
- fprintf(stdout, "\\author{(generated by sgf2misc)}\n");
- fprintf(stdout, "\\date {");
- text2tex((g->gm_date) ? g->gm_date : "");
- fprintf(stdout, "}\n");
- fprintf(stdout, "\\begin{document}\n");
- fprintf(stdout, "\\maketitle\n");
- fprintf(stdout, "\\clearpage\n");
-
- /*
- * One or twocolumn depends on the mode and the diagram size
- */
- if ((prn_dev == DEVICE_EPS && epsf.eps_size <= 200) ||
- (prn_dev == DEVICE_TEX ))
- fprintf(stdout, "\\twocolumn\n");
-
- /*
- * Section header
- */
- fprintf(stdout, "\\section{The Game}\n");
-
- /*
- * Game header (players, rank, date, place and result)
- */
- fprintf(stdout, "\\Black{");
- text2tex((g->gm_black) ? g->gm_black : "NN");
- fprintf(stdout, "}{");
- text2tex((g->gm_brank) ? g->gm_brank : "NR");
- fprintf(stdout, "}\n");
- fprintf(stdout, "\\White{");
- text2tex((g->gm_white) ? g->gm_white : "NN");
- fprintf(stdout, "}{");
- text2tex((g->gm_wrank) ? g->gm_wrank : "NR");
- fprintf(stdout, "}\n");
- fprintf(stdout, "\\Date{");
- text2tex((g->gm_date) ? g->gm_date : "");
- fprintf(stdout, "}\n");
- fprintf(stdout, "\\Place{");
- text2tex((g->gm_place) ? g->gm_place : "");
- fprintf(stdout, "}\n");
- fprintf(stdout, "\\Result{");
- text2tex((g->gm_result) ? g->gm_result : "");
- fprintf(stdout, "}\n");
- }
-
- /* #]tex_header: */
- /* #[tex_trailer: */
-
- static void
- tex_trailer()
- {
- if (statout) {
- /*#[Name:*/
-
- fprintf(stdout, "%%%% #[By name:\n");
- fprintf(stdout, "\\clearpage\n");
- fprintf(stdout, "\\section{Kibitzers sorted by name}\n");
- kib_list(0, "\\kdict");
- fprintf(stdout, "%%%% #]By name: \n");
-
- /*#]Name:*/
- /*#[Rank:*/
-
- fprintf(stdout, "%%%% #[By rank:\n");
- fprintf(stdout, "\\vskip1000pt\n");
- fprintf(stdout, "\\section{Kibitzers sorted by rank}\n");
- kib_list(1, "\\krank");
- fprintf(stdout, "%%%% #]By rank: \n");
-
- /*#]Rank:*/
- /*#[Freq:*/
-
- fprintf(stdout, "%%%% #[By frequency:\n");
- fprintf(stdout, "\\vskip1000pt\n");
- fprintf(stdout, "\\section{Kibitzers sorted by frequency}\n");
- kib_list(2, "\\kfreq");
- fprintf(stdout, "%%%% #]By frequency: \n");
-
- /*#]Freq:*/
- /*#[Byte:*/
-
- fprintf(stdout, "%%%% #[By amount:\n");
- fprintf(stdout, "\\vskip1000pt\n");
- fprintf(stdout, "\\section{Kibitzers sorted by amount}\n");
- kib_list(3, "\\kbyte");
- fprintf(stdout, "%%%% #]By amount: \n");
-
- /*#]Byte:*/
- }
-
- fprintf(stdout, "\\end{document}\n");
- fprintf(stderr, "\n"); /* To flush the messages on stderr */
- }
-
- /* #]tex_trailer: */
- /* #[tex_text: */
-
- static void
- tex_text(m, label)
- GOMOVE *m;
- int label; /* Do we need to label the text comment */
- {
- TEXT *t;
- char lastname[MAXUSER];
-
- /*
- * Collect kibitz statistics
- */
- kib_add(m->mv_text);
-
- if (!textout) return;
- lastname[0] = 0;
- if (label)
- fprintf(stdout,
- "\\n{%s: %d}\n",
- (m->mv_side == BLACK) ? "Black" : "White",
- m->mv_nr);
- for (t = m->mv_text; t != (TEXT *) 0; t = t->cc_next) {
- if (strcmp(lastname, t->cc_name)) {
- /*
- * New username
- */
- strcpy(lastname, t->cc_name);
- fprintf(stdout, "\\k{");
- text2tex((t->cc_name) ? t->cc_name : "NN");
- fprintf(stdout, "}{(");
- text2tex((t->cc_rank) ? t->cc_rank : "NR");
- fprintf(stdout, ")}{");
- } else {
- /*
- * Same username
- */
- fprintf(stdout, "\\k{}{}{"/*}*/);
- }
- text2tex(t->cc_text);
- fprintf(stdout, "}\n");
- }
- }
-
- /* #]tex_text: */
- /* #[text2tex: */
-
- static void
- text2tex(t)
- /*
- * Copy t to standard output while taking care of LaTeX special characters.
- */
- char *t;
- {
- for (; *t; t++) {
- /*
- * Special characters
- */
- if (*t == '_' || *t == '#' || *t == '{' || *t == '}' ||
- *t == '&' || *t == '%' || *t == '$') {
- fprintf(stdout, "\\%c", *t);
- } else
-
- /*
- * Accent characters
- */
- if (*t == '^') {
- fprintf(stdout, "\\%c{}", *t);
- } else
-
- /*
- * Math characters
- */
- if (*t == '+' || *t == '-' ||
- *t == '<' || *t == '>' ||
- *t == '|' || *t == '=') {
- fprintf(stdout, "$%c$", *t);
- } else
-
- /*
- * Backslash
- */
- if (*t == '~') {
- fprintf(stdout, "\\Tilde%c", (*(t+1) == ' ') ? '\\' : ' ');
- } else
-
- /*
- * Backslash
- */
- if (*t == '\\')
- fprintf(stdout, "$\\backslash$");
-
- else putc(*t, stdout);
- }
- }
-
- /* #]text2tex: */
- /* #[move2tex: */
-
- static void
- move2tex(gogame, m1, m2, diagram)
- /*
- * Emit a diagram from move m1 up to and including m2.
- * m1 may be equal to m2.
- */
- GOGAME *gogame;
- GOMOVE *m1;
- GOMOVE *m2;
- int diagram;
- {
- int move_min = m1->mv_nr;
- int move_max = (m1 == m2 || m2 == (GOMOVE *) 0) ? move_min : m2->mv_nr;
-
- /*
- * Keep diagram and caption on the same page
- */
- fprintf(stdout, "\\vbox{%%\n");
-
- /*
- * Print the PS file/emit the TeX diagram
- */
- game2eps(gogame, diagram, move_min, move_max);
-
- /*
- * Print the diagram caption
- */
- if (move_min == move_max) {
- /*
- * Single move diagram
- */
- switch (prn_dev) {
- case DEVICE_TEX:
- /*
- * Print the diagram moves/caption
- */
- fprintf(stdout, " \\texmove{%d}{%s}{%d}\n",
- diagram,
- (m1->mv_side == BLACK) ? "Black" : "White", m1->mv_nr);
- break;
- case DEVICE_EPS:
- /*
- * Print the diagram moves/caption
- */
- fprintf(stdout, " \\epsmove{%s%c%s.%03d}{%s}{%d}\n",
- epsf.eps_dir, PATHSEP, epsf.eps_name,
- diagram,
- (m1->mv_side == BLACK) ? "Black" : "White", m1->mv_nr);
- break;
- }
- } else {
- /*
- * Multiple move diagram
- */
- switch (prn_dev) {
- case DEVICE_TEX:
- /*
- * Print the diagram moves/caption
- */
- fprintf(stdout, " \\texmoves{%d}{%s}{%d}{%s}{%d}\n",
- diagram,
- (m1->mv_side == BLACK) ? "Black" : "White", m1->mv_nr,
- (m2->mv_side == BLACK) ? "Black" : "White", m2->mv_nr);
- break;
- case DEVICE_EPS:
- /*
- * Print the diagram moves/caption
- */
- fprintf(stdout, " \\epsmoves{%s%c%s.%03d}{%s}{%d}{%s}{%d}\n",
- epsf.eps_dir, PATHSEP, epsf.eps_name,
- diagram,
- (m1->mv_side == BLACK) ? "Black" : "White", m1->mv_nr,
- (m2->mv_side == BLACK) ? "Black" : "White", m2->mv_nr);
- break;
- }
- }
-
- /*
- * Keep diagram and caption on the same page
- */
- fprintf(stdout, "}\n");
- }
-
- /* #]move2tex: */
-